a11y: Emit ChildrenChanged for toplevel list changes
authorEmmanuele Bassi <ebassi@gnome.org>
Wed, 21 Oct 2020 14:37:57 +0000 (15:37 +0100)
committerEmmanuele Bassi <ebassi@gnome.org>
Wed, 21 Oct 2020 14:37:57 +0000 (15:37 +0100)
GtkAtSpiRoot is not a context, which means it needs to emit
ChildrenChanged events by itself whenever a toplevel is added to, or
removed from, the list of toplevels.

gtk/a11y/gtkatspiroot.c

index 75290623ea4b5494291b32923f080a3af03108d3..8c35fb6a29c93bff7c9198d0c682ac9f63e04837 100644 (file)
@@ -405,6 +405,46 @@ static const GDBusInterfaceVTable root_accessible_vtable = {
   NULL,
 };
 
+static void
+root_toplevels__items_changed (GtkAtSpiRoot *self,
+                               guint         position,
+                               guint         removed,
+                               guint         added,
+                               GListModel   *toplevels)
+{
+  GtkWidget *window = g_list_model_get_item (self->toplevels, position);
+  GVariant *window_ref = NULL;
+
+  if (window == NULL)
+    {
+      window_ref = gtk_at_spi_null_ref ();
+    }
+  else
+    {
+      GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (window));
+
+      window_ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
+    }
+
+  if (added == 1 && removed == 0)
+    gtk_at_spi_emit_children_changed (self->connection,
+                                      self->root_path,
+                                      GTK_ACCESSIBLE_CHILD_STATE_ADDED,
+                                      position,
+                                      gtk_at_spi_root_to_ref (self),
+                                      window_ref);
+  else if (removed == 1 && added == 0)
+    gtk_at_spi_emit_children_changed (self->connection,
+                                      self->root_path,
+                                      GTK_ACCESSIBLE_CHILD_STATE_REMOVED,
+                                      position,
+                                      gtk_at_spi_root_to_ref (self),
+                                      window_ref);
+
+  if (window != NULL)
+    g_object_unref (window);
+}
+
 static void
 on_registration_reply (GObject      *gobject,
                        GAsyncResult *result,
@@ -439,6 +479,9 @@ on_registration_reply (GObject      *gobject,
 
   /* Monitor the top levels */
   self->toplevels = gtk_window_get_toplevels ();
+  g_signal_connect_swapped (self->toplevels, "items-changed",
+                            G_CALLBACK (root_toplevels__items_changed),
+                            self);
 }
 
 static void